/*
 * Header file contenente le dichiarazioni della struttura dati comune.
 */

#include <iostream>
#include <fstream>

//#define DEBUG_MODE

#ifdef DEBUG_MODE

extern unsigned int MASK ;

#define DBG(A, B) {if ((A) & MASK) {B; } }

#else

/* Definendo questa macro si disattivano le assert se la macro
    DEBUG_MODE non è definita */
#define NDEBUG
#define DBG(A, B)

#endif

#define D0(a)
#define D1(a) DBG(1, a)
#define D2(a) DBG(2, a)

#include <cassert>

/* Inizio header del modulo Struttura Dati */

const int MAXLUN   = 300 ; /* Lunghezza massima stringhe */
const int DIM_BASE = 100 ; /* Dimensione minima dell'array in cui è
			        memorizzata una sequenza */

/* La chiave degli elementi di una sequenza può essere un numero
 * intero positivo oppure una parola.
 * Si poteva utilizzare un tipo booleano per il tipo della chiave, ma,
 * siccome il tipo della chiave è un parametro di ingresso della
 * funzione che inizializza la sequenza, usare gli enumeratori aumenta
 * la leggibilità (dal nome dell'enumeratore passato alla funzione di
 * inizializzazione si deduce immediatamente il tipo della chiave).
 */
enum tipo_chiave_t {CHIAVE_NUMERICA, CHIAVE_STRINGA} ;


/* Struttura dell'elemento contenente una parola in una lista di parole.
 */
struct parola_elem {
    char parola[MAXLUN] ;
    parola_elem *pross ;
} ;

/* Ogni elemento contiene un campo chiave che può essere una parola o
 * un valore intero positivo. Per implementare le due possibilita',
 * memorizziamo comunque la chiave in una stringa. Nel caso in cui la
 * chiave debba essere un valore intero positivo, memorizziamo nella
 * stringa la sua rappresentazione in base 10.
 */
struct elem {
    char chiave[MAXLUN] ;       /* campo chiave */
   parola_elem *lista_parole ; /* puntatore alla lista di parole */
    
} ;

typedef elem * elem_p ;

/* Gli elementi della sequenza possono avere come chiave o tutti un
 * valore intero positivo o tutti una parola.
 */
struct desc_sequenza {
    elem_p *elementi ; /* La sequenza è implementata mediante un array
		       * dinamico di puntatori ad oggetti di tipo elem
		       * e non un mediante array dinamico di oggetti di tipo
		       * elem.  Questo perché, date le dimensioni
		       * degli oggetti di tipo elem, la prima
		       * soluzione permette di effettuare lo
		       * spostamento di O(N) elementi (a seguito di
		       * inserimenti ed estrazioni) ad un costo
		       * inferiore
		       */
    int num_elem ;   /* numero di elementi corrente */
    int dim ;        /* dimensioni correnti dell'array */
    bool ordinata ;  /* vero se e solo se e' garantito che la
		         sequenza sia ordinata */
    tipo_chiave_t tipo_chiave ; /* Tipo chiave */ 
} ;

/* Posizione in cui inserire l'elemento: in testa, in coda, in ordine */
enum ins_modo {in_testa, in_coda, in_ordine} ;

/* Fine header modulo Struttura Dati */
